package chapter14_1;

import lombok.Getter;
import lombok.Setter;

import java.lang.ref.WeakReference;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author eric
 * Description: 线程终止标志位
 */
public class TerminationToken {

    /**
     * 无锁的请求下当数据修改后其他线程可以读取到，是否停止标志
     * 需要加上volatile 来实现线程间的数据共享
     */
    @Getter
    @Setter
    private volatile boolean toShutDown = false;

    /**
     * 当多个线程共享一个terminationToken实例时，通过队列的方式来记录所有的停止线程，减少锁的方式来实现
     */
    private Queue<WeakReference<Termination>> coordinatedThreads;

    /**
     * 设置未执行的任务数
     */
    public final AtomicInteger reservations = new AtomicInteger(0);

    public TerminationToken() {
        this.coordinatedThreads = new ConcurrentLinkedDeque<>();
    }

    /**
     * 注册一个可以两阶段终止的线程
     *
     * @param terminationThread 待终止的线程
     */
    public void register(Termination terminationThread) {
        coordinatedThreads.add(new WeakReference<>(terminationThread));
    }

    /**
     * 通知队列中的所有线程停止， 通过interrupt暴力停止
     *
     * @param terminationThread 当前线程
     */
    public void noytifyAllThreadTermination(Termination terminationThread) {
        WeakReference<Termination> wrThread;
        Termination otherThread;

        while ((wrThread = coordinatedThreads.poll()) != null) {
            otherThread = wrThread.get();
            if (otherThread != null && otherThread != terminationThread) {
                // 终止线程
                otherThread.terminate();
            }
        }
    }
}
